package com.ics.cmsadmin.modules.auth.service.impl;

import com.ics.cmsadmin.frame.core.annotation.CacheDbMember;
import com.ics.cmsadmin.frame.core.annotation.ClearDbMember;
import com.ics.cmsadmin.frame.core.bean.PageBean;
import com.ics.cmsadmin.frame.core.bean.PageResult;
import com.ics.cmsadmin.frame.core.enums.ApiResultEnum;
import com.ics.cmsadmin.frame.core.enums.CacheGroupEnum;
import com.ics.cmsadmin.frame.core.exception.CmsException;
import com.ics.cmsadmin.modules.auth.bean.SysMenu;
import com.ics.cmsadmin.modules.auth.dao.MenuDao;
import com.ics.cmsadmin.modules.auth.service.MenuService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

import static com.ics.cmsadmin.modules.auth.steward.AuthRepositories.menuDao;
import static com.ics.cmsadmin.modules.auth.steward.AuthServices.roleMenuService;

/**
 * Created by lvsw on 2018-03-29.
 */
@Service
public class MenuServiceImpl implements MenuService {

    @CacheDbMember(returnClass = SysMenu.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public SysMenu queryById(String id) {
        if (StringUtils.isBlank(id)){
            return null;
        }
        return menuDao.queryById(id);
    }

    @CacheDbMember(returnClass = SysMenu.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public PageResult<SysMenu> list(SysMenu menu, PageBean page) {
        long count = menuDao.count(menu);
        if (count == 0){
            return new PageResult<>();
        }
        page = page == null ? new PageBean() : page;
        return PageResult.getPage(count, menuDao.list(menu, page));
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean insert(SysMenu menu) {
        if (menu == null){
            return false;
        }
        if (StringUtils.isBlank(menu.getMenuId())){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_NULL_PRIMARY);
        }
        if (queryById(menu.getMenuId()) != null){
            throw new CmsException(ApiResultEnum.INSERT_TABLE_REPEAT_PRIMARY);
        }
        if (StringUtils.isBlank(menu.getParentId()) || StringUtils.equals(menu.getParentId(), DEFAULT_ROOT_ID)){
            menu.setParentId(DEFAULT_ROOT_ID);
        }else{
            if(queryById(menu.getParentId()) == null){
                throw new CmsException(ApiResultEnum.INSERT_TABLE_ITEM_FAIL, "父节点没有找到");
            }
        }
        return menuDao.insert(menu) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean update(String id, SysMenu menu) {
        if (StringUtils.isBlank(id) || menu == null || queryById(id) == null){
            throw new CmsException(ApiResultEnum.UPDATE_TABLE_ITEM_FAIL);
        }
        return menuDao.update(id, menu) == 1;
    }

    @ClearDbMember(group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public boolean delete(String id) {
        if (StringUtils.isBlank(id) || queryById(id) == null){
            throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL);
        }
        if (CollectionUtils.isNotEmpty(listDirectChildren(id))){
            throw new CmsException(ApiResultEnum.DELETE_TABLE_ITEM_FAIL,  "该菜单节点拥有子菜单,不能删除");
        }
        boolean result = (menuDao.delete(id) == 1);
        if (result){
            roleMenuService.deleteRoleMenuByMenuId(id);
        }
        return result;
    }

    @CacheDbMember(returnClass = SysMenu.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public SysMenu queryParent(String childrenId) {
        return null;
    }

    @CacheDbMember(returnClass = SysMenu.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public List<SysMenu> listMenuTreeByUserId(String loginUserId) {
        return listMenuTreeByUserId(DEFAULT_ROOT_ID,  loginUserId);
    }

    private List<SysMenu> listMenuTreeByUserId(String parentNode, String loginUserId) {
        List<SysMenu> list = listDirectChildrenByUserId(parentNode, loginUserId);
        if (CollectionUtils.isEmpty(list)){
            return null;
        }
        for (SysMenu t : list){
            t.setChildren(listMenuTreeByUserId(t.getMenuId(), loginUserId));
        }
        return list;
    }

    private List<SysMenu> listDirectChildrenByUserId(String parentNode, String loginUserId) {
        return menuDao.listDirectChildrenByUserId(parentNode, loginUserId);
    }

    @CacheDbMember(returnClass = SysMenu.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public List<SysMenu> listDirectChildren(String parentId) {
        if (StringUtils.isBlank(parentId)){
            parentId = DEFAULT_ROOT_ID;
        }
        return menuDao.listDirectChildren(parentId);
    }

    @CacheDbMember(returnClass = SysMenu.class, group = CacheGroupEnum.CACHE_AUTH_GROUP)
    @Override
    public List<SysMenu> listAllChildren() {
        return listAllChildren(DEFAULT_ROOT_ID);
    }

    private List<SysMenu> listAllChildren(String parentNode){
        List<SysMenu> list = listDirectChildren(parentNode);
        if (CollectionUtils.isEmpty(list)){
            return null;
        }
        for (SysMenu t : list){
            t.setChildren(listAllChildren(t.getMenuId()));
        }
        return list;
    }
}
